package com.siwei.infoextract.web;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import com.siwei.infoextract.SystemConfig;
import com.siwei.infoextract.rule.RuleEngine;
import com.siwei.infoextract.util.Utility;
import com.siwei.infoextract.wrapper.InfoBlocksExtractor;
import com.siwei.infoextract.wrapper.featureextract.InnerTextFeatureExtractor;
import com.siwei.infoextract.wrapper.parser.DomNode;
import com.siwei.infoextract.wrapper.parser.DomNodeIteratorCallback;
import com.siwei.infoextract.wrapper.parser.DomTreeTraversal;

public class ExtractServlet extends HttpServlet {
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		service(request, response);
	}

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		service(request, response);
	}

	public void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// Create a factory for disk-based file items
		DiskFileItemFactory factory = new DiskFileItemFactory();

		// Set factory constraints
		// factory.setSizeThreshold(yourMaxMemorySize);
		// factory.setRepository(yourTempDirectory);

		// Create a new file upload handler
		ServletFileUpload upload = new ServletFileUpload(factory);

		// Set overall request size constraint
		// upload.setSizeMax(yourMaxRequestSize);

		// Parse the request
		
		
		
		try {
			List /* FileItem */items = upload.parseRequest(request);

			// Process the uploaded items
			String uploadDir = SystemConfig.getValue("file.upload.dir");
			File uploadFile = null;
			Iterator iter = items.iterator();
			while (iter.hasNext()) {
				FileItem item = (FileItem) iter.next();

				if (!item.isFormField()) {
					if (item.getName() != null
							&& !item.getName().trim().equals("")) {
						uploadFile = new File(uploadDir + File.separator
								+ item.getName());
						item.write(uploadFile);
					}
					break;
				} else {
					// skip form field in this servlet
				}
			}

			System.out.println("uploadFile:" + uploadFile);
			if (uploadFile != null) {
				DomNode root = Utility.parseDomNodeFromFile(uploadFile.getAbsolutePath());

				InfoBlocksExtractor extractor = new InfoBlocksExtractor();
				List<DomNode> results = extractor.extract(root);

				final StringBuffer stringBuffer = new StringBuffer();
				final InnerTextFeatureExtractor innerTextExtractor = new InnerTextFeatureExtractor();
				for(Iterator<DomNode> resultsIter = results.iterator(); resultsIter.hasNext();) {
					DomTreeTraversal traversal = new DomTreeTraversal(resultsIter.next());
					traversal.addCallback(new DomNodeIteratorCallback(){
						public void call(DomNode domNode) {
							String innerText = (String)innerTextExtractor.extract(domNode);
							Map<String, String> map = (Map<String, String>)domNode.getFlag();
							if (map.get(RuleEngine.TITLE_RULE_ENGINE_NAME) != null) {
								boolean isTitle = Boolean.parseBoolean(map.get(RuleEngine.TITLE_RULE_ENGINE_NAME));
								if (isTitle) {
									stringBuffer.append(innerText);
								}
							}

							if (map.get(RuleEngine.ADDRESS_RULE_ENGINE_NAME) != null) {
								boolean isAddress = Boolean.parseBoolean(map.get(RuleEngine.ADDRESS_RULE_ENGINE_NAME));
								if (isAddress) {
									stringBuffer.append(innerText);
								}
							}
							if (map.get(RuleEngine.PHONE_RULE_ENGINE_NAME) != null) {
								boolean isPhone = Boolean.parseBoolean(map.get(RuleEngine.PHONE_RULE_ENGINE_NAME));
								if (isPhone) {
									stringBuffer.append(innerText);
								}
							}
						}
					});
					traversal.traverse();
					stringBuffer.append("<br>");
				}

				request.setAttribute("extractList", stringBuffer);
			}

		} catch (FileUploadException fue) {
			fue.printStackTrace();
			throw new IOException(fue.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
			throw new IOException(e.getMessage());
		}
		request.getRequestDispatcher("/extractResult.jsp").forward(request, response);
		//response.sendRedirect(request.getContextPath() + "/extractResult.jsp");
	}
}
